package com.google.code.gronono.gps.ui;

import java.awt.CardLayout;
import java.awt.Toolkit;
import java.net.URL;

import javax.swing.GroupLayout;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.GroupLayout.Alignment;
import javax.swing.LayoutStyle.ComponentPlacement;

import com.google.code.gronono.commons.swing.SwingUtils;
import com.google.code.gronono.gps.ui.controller.GPSController;
import com.google.code.gronono.gps.ui.panels.ButtonsPanel;
import com.google.code.gronono.gps.ui.panels.HeaderPanel;
import com.google.code.gronono.gps.ui.panels.pages.AbstractPagePanel;
import com.google.code.gronono.gps.ui.panels.pages.OptionsPanel;
import com.google.code.gronono.gps.ui.panels.pages.PreviewPanel;
import com.google.code.gronono.gps.ui.panels.pages.SortPanel;

import fr.gronono.gbundle.Bundle;

/**
 * Frame principale de l'application GPS.
 */
@Bundle("com.google.code.gronono.gps.gui")
public class GPSFrame extends JFrame {
	/** serialVersionUID. */
	private static final long serialVersionUID = -8940302108688913761L;

	/** Titre de l'application. */
	@Bundle("gps.app.name")
	private static String APP_NAME;
	/** Icône de l'application. */
	@Bundle("gps.app.icon")
	private static String APP_ICON;
	/** Icône de l'assistant. */
	@Bundle("gps.wizard.icon")
	private static String WIZ_ICON;

	/** Contrôleur. */
	private final GPSController controller;

	/** Panel des boutons action. */
	private ButtonsPanel buttonsPanel;
	/** Panel du header. */
	private HeaderPanel headerPanel;
	/** Panel des options. */
	private OptionsPanel optionsPanel;
	/** Panel aperçu. */
	private PreviewPanel previewPanel;
	/** Panel résultat de tri. */
	private SortPanel sortPanel;

	/** Panel composant les pages. */
	private JPanel pagesPanel;

	/**
	 * Constructeur.
	 * @param controller Le contrôleur.
	 */
	public GPSFrame(final GPSController controller) {
		super(APP_NAME);
		this.controller = controller;

		final URL url = this.getClass().getClassLoader().getResource(APP_ICON);
		this.setIconImage(Toolkit.getDefaultToolkit().getImage(url));

		initComponents();
		placeComponents();
	}

	/**
	 * Initialisation des composants graphiques.
	 */
	private void initComponents() {
		headerPanel = new HeaderPanel();
		final URL url = this.getClass().getClassLoader().getResource(WIZ_ICON);
		headerPanel.setIcon(new ImageIcon(url));

		buttonsPanel = new ButtonsPanel(this.controller);
		optionsPanel = new OptionsPanel(this.controller);
		previewPanel = new PreviewPanel(this.controller);
		sortPanel = new SortPanel(this.controller);

		pagesPanel = new JPanel(new CardLayout());
		pagesPanel.add(optionsPanel, optionsPanel.getClass().getName());
		pagesPanel.add(previewPanel, previewPanel.getClass().getName());
		pagesPanel.add(sortPanel, sortPanel.getClass().getName());
	}

	/**
	 * Placement des composants graphiques.
	 */
	private void placeComponents() {
		final GroupLayout layout = new GroupLayout(this.getContentPane());
		this.getContentPane().setLayout(layout);

		// Horizontalement
		layout.setHorizontalGroup(
	            layout.createParallelGroup(Alignment.LEADING)
	            .addGroup(layout.createSequentialGroup()
	                .addGroup(layout.createParallelGroup(Alignment.LEADING)
	                    .addGroup(layout.createSequentialGroup()
	                        .addContainerGap()
	                        .addComponent(pagesPanel)
	                        .addContainerGap())
	                    .addComponent(buttonsPanel)))
	            .addComponent(headerPanel)
	        );
		// Verticalement
        layout.setVerticalGroup(
            layout.createParallelGroup(Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(headerPanel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(ComponentPlacement.RELATED)
                .addComponent(pagesPanel)
                .addPreferredGap(ComponentPlacement.RELATED)
                .addComponent(buttonsPanel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
        );

        SwingUtils.pack(this);
	}

	/** Afficher la page des options. */
	public void displayOptions() {
		displayPage(optionsPanel);
	}

	/** Afficher la page d'aperçu. */
	public void displayPreview() {
		previewPanel.refresh();
		displayPage(previewPanel);
	}

	/** Afficher la page de résultat de tri. */
	public void displaySort() {
		sortPanel.refresh();
		displayPage(sortPanel);
	}

	/**
	 * Affiche la page spécifiée.
	 * @param page La page à afficher.
	 */
	private void displayPage(final AbstractPagePanel page) {
		// Récupération du layout pour lui faire afficher la page
		final CardLayout layout = (CardLayout) this.pagesPanel.getLayout();
		layout.show(this.pagesPanel, page.getClass().getName());
		// Mise à jour du header
		headerPanel.setTitle(page.getTitle());
		headerPanel.setDescription(page.getDescription());
	}

	/**
	 * Réinitialiser la page des options avec les options par défaut.
	 */
	public void resetOptions() {
		optionsPanel.initValues();
	}

}
